<cfcomponent output="false">
	<cfset $ = application.helpers />
	<cfset uuidExclusions = "google_calendar_id,google_event_id" />
	
	<!--- --->
	
	<cffunction name="save" access="public" output="true" returntype="string">
		<cfargument name="table" required="true" />
		<cfargument name="id" required="false" default="" />
	
		<cfset var local = {} />
		
		<cfif arguments.id eq "">
			<cfset local.id = _dbInsert(argumentCollection=arguments) />
		<cfelse>
			<cfset local.id = _dbUpdate(argumentCollection=arguments) />
		</cfif>
		
		<cfreturn local.id />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="_dbUpdate" access="private" output="true" returntype="string">

		<cfset var local = {} />
		
		<cfset local.id = arguments.id />
		<cfset local.table = application.vars.db[arguments.table] />
		<cfset local.script = "" />
		
		<cfset structDelete(arguments,"table") />
		<cfset structDelete(arguments,"id") />
		<cfset structDelete(arguments,"cfc") />
		<cfset structDelete(arguments,"callMethod") />
		
		<cfloop collection="#arguments#" item="local.i">
			<cfif arguments[local.i] eq "">
				<cfset arguments[local.i] = "null" />
				<cfset local.script = listAppend(local.script,local.i & " = " & arguments[local.i]) />
			<cfelse>
				<cfif right(local.i,3) eq '_id' and len(arguments[local.i]) eq 32 and not uuidExclusions contains local.i>
					<cfset local.script = listAppend(local.script,local.i & " = " & "unhex('#arguments[local.i]#')") />
				<cfelse>
					<cfif local.i contains 'date' and len(arguments[local.i]) eq 10>
						<cfset arguments[local.i] = $.format.date(arguments[local.i]) />
					</cfif>
					<cfset arguments[local.i] = replace(arguments[local.i],"'","\'","ALL") />
					<cfset local.script = listAppend(local.script,local.i & " = '" & arguments[local.i] & "'") />
				</cfif>
			</cfif>
		</cfloop>
		
		<cfif local.table.timestamp>
			<cfset local.script = local.script & ", modified = now()" />
		</cfif>

		<cftransaction>
			<cfquery name="local.dbupdate" datasource="#$.site.getVar('datasource')#">
				update #local.table.name#
				set #local.script#
				where id = unhex('#local.id#')
			</cfquery>
		</cftransaction>

		<cfreturn local.id />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="_dbInsert" access="private" output="true" returntype="string">

		<cfset var local = {} />
		
		<!--- capture the values which will be removed from arguments --->
		<cfset local.table = application.vars.db[arguments.table] />
		
		<cfset local.columns = "" />
		<cfset local.values = "" />
		
		<!--- remove from arguments --->
		<cfset structDelete(arguments,"table") />
		<cfset structDelete(arguments,"id") />
		<cfset structDelete(arguments,"cfc") />
		<cfset structDelete(arguments,"callMethod") />
		
		<cfloop collection="#arguments#" item="local.i">
			<cfset replace(local.i,"'","''","ALL") />
			<cfif IsSimpleValue(arguments[local.i])>
				<cfif arguments[local.i] eq ""> <!--- set script to save null --->
					<cfset arguments[local.i] = "null" />
					<cfset local.values = listAppend(local.values,arguments[local.i]) />
				<cfelse>
					<cfif right(local.i,3) eq '_id' and len(arguments[local.i]) eq 32 and not uuidExclusions contains local.i>
						<cfset local.values = listAppend(local.values,"unhex('#arguments[local.i]#')") />
					<cfelse>
						<cfif local.i contains 'date' and len(arguments[local.i]) eq 10>
							<cfset arguments[local.i] = $.format.date(arguments[local.i]) />
						</cfif>
						<cfset arguments[local.i] = replace(arguments[local.i],"'","\'","ALL") />
						<cfset local.values = listAppend(local.values,"'" & arguments[local.i] & "'") />
					</cfif>
				</cfif>
				<cfset local.columns = listAppend(local.columns,local.i) />
			</cfif>
		</cfloop>
		
		<cfif local.table.active>
			<cfset local.columns = listAppend(local.columns,'active') />
			<cfset local.values = listAppend(local.values,'1') />
		</cfif>
		
		<cfif local.table.timestamp>
			<cfset local.columns = local.columns & ",created,modified" />
			<cfset local.values = local.values & ",now(),now()" />
		</cfif>
		
		<cfset local.id = newID() />
		
		<cfquery name="local.dbinsert" datasource="#$.site.getVar('datasource')#">
			insert into #local.table.name#(id,#local.columns#)
			values(unhex('#local.id#'),#local.values#)
		</cfquery>
		
		<cfreturn local.id />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="newID" access="public" output="false" returntype="string">

		<cfset var local = {} />
		
		<cfreturn replace(createUUID(),'-','','ALL') />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="delete" access="public" output="false" returntype="string">

		<cfset var local = {} />
		
		<cfset local.table = application.vars.db[arguments.table] />
		
		<cfif arguments.id neq "">
			<cfif local.table.active>
				<cfquery name="local.delete" datasource="#$.site.getVar('datasource')#">
					update #arguments.table# set active = 0
					<cfif local.table.timestamp>
						,modified = now()
					</cfif>
					where id = #uuid(arguments.id)#
				</cfquery>
			<cfelse>
				<cfquery name="local.delete" datasource="#$.site.getVar('datasource')#">
					delete from #arguments.table#
					where id = #uuid(arguments.id)#
				</cfquery>
			</cfif>
		</cfif>
		
		<cfreturn true />
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="uuid" access="public" output="true" returntype="string">
		<cfargument name="id" required="true" />
		
		<cfset var local = {} />
		
		<cfsavecontent variable="local.result">
			unhex(<cfqueryparam value="#arguments.id#" cfsqltype="CF_SQL_VARCHAR" maxlength="32" />)
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="uuids" access="public" output="true" returntype="string">
		<cfargument name="list" required="true" />
		
		<cfset var local = {} />
		<cfset local.iterator = 0 />
		
		<cfsavecontent variable="local.result">
			(<cfloop list="#arguments.list#" index="local.i">
				<cfset local.iterator++ />
				unhex(<cfqueryparam value="#local.i#" cfsqltype="CF_SQL_VARCHAR" maxlength="32" />)
				<cfif local.iterator neq listLen(arguments.list)>,</cfif>
			</cfloop>)
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="string" access="public" output="true" returntype="string">
		<cfargument name="string" required="true" />
		<cfargument name="maxlength" required="false" default="1000" />
		
		<cfset var local = {} />
		
		<cfsavecontent variable="local.result">
			<cfqueryparam value="#arguments.string#" cfsqltype="CF_SQL_VARCHAR" maxlength="#arguments.maxlength#" />
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="strings" access="public" output="true" returntype="string">
		<cfargument name="list" required="true" />
		<cfargument name="maxlength" required="false" default="1000" />
		
		<cfset var local = {} />
		<cfset local.iterator = 0 />
		
		<cfsavecontent variable="local.result">
			(<cfloop list="#arguments.list#" index="local.i">
				<cfset local.iterator++ />
				<cfqueryparam value="#local.i#" cfsqltype="CF_SQL_VARCHAR" maxlength="#arguments.maxlength#" />
				<cfif local.iterator neq listLen(arguments.list)>,</cfif>
			</cfloop>)
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="datetime" access="public" output="true" returntype="string">
		<cfargument name="datetime" required="true" hint="railo format mm/dd/yyyy HH:nn:ss" />
		
		<cfset var local = {} />
		
		<cfset local.database_datetime = dateTimeFormat(arguments.datetime,'yyyy-mm-dd HH:nn:ss') />
		
		<cfsavecontent variable="local.result">
			<cfqueryparam value="#local.database_datetime#" cfsqltype="cf_sql_timestamp" />
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="int" access="public" output="true" returntype="string">
		<cfargument name="value" required="true" />
		
		<cfset var local = {} />
		
		<cfsavecontent variable="local.result">
			<cfqueryparam value="#arguments.value#" cfsqltype="CF_SQL_INTEGER" />
		</cfsavecontent>
		
		<cfreturn local.result />

	</cffunction>
	
	<!--- --->
	
</cfcomponent>